﻿#region Using References

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;
using Beaker.Services.Interfaces;
using Beaker.Services.Locator;

#endregion

namespace Beaker.Services
{
	/// <summary>
	/// Service to provide access to the IO System (Files and Folders)
	/// </summary>
	[Obsolete( "switch to IFileSystemService" )]
	public class IOService
		: IIOService
	{
		// default to use, when there is no service locator or it has none
		private static readonly IIOService _default = new IOService();

		[Obsolete( "switch to IFileSystemService" )]
		public static IIOService Default
		{
			get
			{
				Contract.Ensures( Contract.Result<IIOService>() != null );
				return ServiceLocator.Provide( _default );
			}
		}

		/// <summary>
		/// Gets the path to the given special folder
		/// </summary>
		/// <param name="folder">The special folder to get the path for</param>
		/// <returns>The path to the given special folder</returns>
		public string GetSpecialFolderPath( Environment.SpecialFolder folder )
		{
			// Contract.Requires<ArgumentOutOfRangeException>( Enum.IsDefined( typeof( Environment.SpecialFolder ), folder ) );
			Contract.Ensures( Contract.Result<string>() != null );

			return Environment.GetFolderPath( folder );
		}

		/// <summary>
		/// Get a list of the directories
		/// </summary>
		/// <param name="path">The path to search for folders.</param>
		/// <returns>A sequence of all the full directory names.</returns>
		public IEnumerable<string> GetFolders( string path )
		{
			// Contract.Requires<ArgumentNullException>( !string.IsNullOrEmpty( path ) );
			Contract.Ensures( Contract.Result<IEnumerable<string>>() != null );

			foreach( string subDirectoryPath in Directory.GetDirectories( path, "*", SearchOption.TopDirectoryOnly ) )
				yield return subDirectoryPath;
		}

		/// <summary>
		/// Get a list of the files
		/// </summary>
		/// <param name="path">The path to search for files</param>
		/// <returns>A sequence of all the full file names.</returns>
		public IEnumerable<string> GetFiles( string path )
		{
			Contract.Requires<ArgumentNullException>( !string.IsNullOrEmpty( path ) );
			Contract.Ensures( Contract.Result<IEnumerable<string>>() != null );

			foreach( string filePath in Directory.GetFiles( path, "*", SearchOption.TopDirectoryOnly ) )
				yield return filePath;
		}

		/// <summary>
		/// Get a list of the files
		/// </summary>
		/// <param name="path">The path to search for files</param>
		/// <param name="filter">The filter to filter the filers on.</param>
		/// <returns>
		/// A sequence of all the full file names.
		/// </returns>
		public IEnumerable<string> GetFiles( string path, string filter )
		{
			// Contract.Requires<ArgumentNullException>( !string.IsNullOrEmpty( path ) );
			Contract.Ensures( Contract.Result<IEnumerable<string>>() != null );

			foreach( string filePath in Directory.GetFiles( path, filter, SearchOption.TopDirectoryOnly ) )
				yield return filePath;
		}

		/// <summary>
		/// Get a list of the files
		/// </summary>
		/// <param name="path">The path to search for files</param>
		/// <param name="filter">The filter to filter the filers on.</param>
		/// <param name="searchOption">The search option.</param>
		/// <returns>
		/// A sequence of all the full file names.
		/// </returns>
		public IEnumerable<string> GetFiles( string path, string filter, SearchOption searchOption )
		{
			// Contract.Requires<ArgumentNullException>( !string.IsNullOrEmpty( path ) );
			Contract.Ensures( Contract.Result<IEnumerable<string>>() != null );

			foreach( string filePath in Directory.GetFiles( path, filter, searchOption ) )
				yield return filePath;
		}

		/// <summary>
		/// Check if the given file exists
		/// </summary>
		/// <param name="filePath">The path to the file to check.</param>
		/// <returns><c>true</c> when the file exists, otherwise <c>false</c>.</returns>
		public bool FileExists( string filePath )
		{
			Contract.Requires<ArgumentNullException>( !string.IsNullOrEmpty( filePath ) );

			return File.Exists( filePath );
		}

		/// <summary>
		/// Check if the given folder exists
		/// </summary>
		/// <param name="folderPath">The path to the folder to check.</param>
		/// <returns><c>true</c> when the folder exists, otherwise <c>false</c>.</returns>
		public bool FolderExists( string folderPath )
		{
			Contract.Requires<ArgumentNullException>( !string.IsNullOrEmpty( folderPath ) );

			return Directory.Exists( folderPath );
		}

		/// <summary>
		/// Open the file with the given path in read mode
		/// </summary>
		/// <param name="filePath">The file path.</param>
		/// <returns>The stream of the file.</returns>
		public Stream FileOpenRead( string filePath )
		{
			Contract.Requires<ArgumentNullException>( !string.IsNullOrEmpty( filePath ) );
			Contract.Ensures( Contract.Result<Stream>() != null );

			return File.OpenRead( filePath );
		}

		/// <summary>
		/// Open the text file with the given path in read mode
		/// </summary>
		/// <param name="filePath">The path to the file to open.</param>
		/// <returns>
		/// The TextReader of the file.
		/// </returns>
		public TextReader FileOpenText( string filePath )
		{
			Contract.Requires<ArgumentNullException>( !string.IsNullOrEmpty( filePath ) );
			Contract.Ensures( Contract.Result<TextReader>() != null );

			return File.OpenText( filePath );

		}
	}
}
